<template>
  <el-container class="flow-select-dialog">
    <el-aside width="240px">
      <el-card
        class="base-card"
        shadow="never"
        :body-style="{ padding: '0px' }"
        style="border: none"
      >
        <el-scrollbar>
          <el-tree
            ref="categoryIdTree"
            :data="categoryIdList"
            :props="{ label: 'name' }"
            node-key="id"
            :highlight-current="true"
            :current-node-key="(currentCategory || {}).id"
            @node-click="onCategoryChange"
          />
        </el-scrollbar>
      </el-card>
    </el-aside>
    <el-main style="margin-left: 20px; display: flex; flex-direction: column">
      <el-form
        ref="formFlow"
        :model="formFilter"
        label-width="80px"
        :size="defaultSize"
        label-position="right"
        @submit.prevent
      >
        <filter-box :item-width="550" @search="refreshFlowList()" @reset="onReset">
          <el-form-item label="流程名称">
            <el-input
              v-model="formFilter.processDefinitionName"
              :clearable="true"
              placeholder="请输入流程名称"
            />
          </el-form-item>
        </filter-box>
      </el-form>
      <div style="flex: 1; background: white; border-radius: 4px">
        <el-scrollbar>
          <vxe-table
            ref="table"
            :row-id="props.props.value"
            :data="filteredFlowList"
            height="490"
            show-overflow="title"
            show-header-overflow="title"
            :row-config="{ height: 35, isHover: true }"
            :checkbox-config="getSelectConfig"
            @checkbox-change="onSelectChange"
            @checkbox-all="onSelectChange"
            @cell-click="onCellClick"
          >
            <vxe-column type="checkbox" width="50" />
            <vxe-column title="流程名称" field="processDefinitionName" />
            <vxe-column title="流程标识" field="processDefinitionKey" />
            <template v-slot:empty>
              <div class="table-empty unified-font">
                <img src="@/assets/img/empty.png" />
                <span>暂无数据</span>
              </div>
            </template>
          </vxe-table>
        </el-scrollbar>
      </div>
      <div class="dialog-footer">
        <el-button @click="onCancel">取消</el-button>
        <el-button type="primary" @click="onSubmit">确认选择</el-button>
      </div>
    </el-main>
  </el-container>
</template>

<script setup lang="ts">
import { reactive, ref, computed, onMounted } from 'vue';
import { VxeTable, VxeColumn, VxeTableDefines } from 'vxe-table';
import { ANY_OBJECT } from '@/types/generic';
import { DialogProp } from '@/components/Dialog/types';
import { FlowEntryController, FlowDictionaryController } from '@/api/flow';
import { DictData } from '@/common/staticDict/types';
import { findItemFromList } from '@/common/utils';

interface IProps {
  value: Array<ANY_OBJECT>;
  props?: ANY_OBJECT;
  flowList?: Array<ANY_OBJECT>;
  dialog?: DialogProp<ANY_OBJECT[]>;
}

const props = withDefaults(defineProps<IProps>(), {
  props: () => ({
    label: 'processDefinitionName',
    value: 'processDefinitionKey',
  }),
  flowList: () => [],
});

const defaultSize = 'default';
const table = ref();
const categoryIdTree = ref();
const categoryIdList = ref<DictData[]>([]);
const currentCategory = ref<DictData>();
const processList = ref<ANY_OBJECT[]>([]);
const dialogSelectItems = ref<ANY_OBJECT[]>([]);

const formFilter = reactive({
  categoryId: undefined as string | number | undefined,
  processDefinitionName: undefined as string | undefined,
});

const formFilterCopy = reactive({
  categoryId: undefined as string | number | undefined,
  processDefinitionName: undefined as string | undefined,
});

const filteredFlowList = computed(() => {
  return processList.value.filter(item => {
    let find = true;
    // 流程名称是否匹配
    if (
      formFilterCopy.processDefinitionName != null &&
      formFilterCopy.processDefinitionName !== ''
    ) {
      find = item.processDefinitionName.indexOf(formFilterCopy.processDefinitionName) !== -1;
    }
    // 流程分类是否匹配
    if (
      formFilterCopy.categoryId != null &&
      formFilterCopy.categoryId !== '' &&
      formFilterCopy.categoryId !== 'all'
    ) {
      find = find && item.categoryId === formFilterCopy.categoryId;
    }
    return find;
  });
});

const getSelectConfig = computed(() => {
  const selectRowKeys = (dialogSelectItems.value || []).map(item => item[props.props.value]);
  return {
    highlight: true,
    checkStrictly: true,
    checkRowKeys: selectRowKeys,
    showHeader: false,
  };
});

const loadCategoryList = () => {
  FlowDictionaryController.dictFlowCategory({})
    .then(res => {
      categoryIdList.value = res.getList();
      categoryIdList.value.unshift({
        id: 'all',
        name: '全部',
      });
      currentCategory.value = categoryIdList.value[0];
      categoryIdTree.value?.setCurrentKey(currentCategory.value.id);
    })
    .catch(e => {
      console.error(e);
    });
};

const refreshFlowList = (reloadData = false) => {
  formFilterCopy.processDefinitionName = formFilter.processDefinitionName;
  formFilterCopy.categoryId = formFilter.categoryId;
};

const onReset = () => {
  formFilter.processDefinitionName = undefined;
  refreshFlowList();
};

const loadFlowList = () => {
  // 如果有传入的流程列表，直接使用
  if (props.flowList && props.flowList.length > 0) {
    processList.value = props.flowList;
    setTableSelectRow();
    return;
  }

  const params = {
    flowEntryDtoFilter: {},
  };

  FlowEntryController.listAllByStartFlow(params)
    .then(res => {
      processList.value = Array.isArray(res.data) ? res.data : res.data?.dataList || [];
      processList.value = processList.value.map(item => ({
        ...item,
        processDefinitionName: item.processDefinitionName || '',
        processDefinitionKey: item.processDefinitionKey || '',
      }));
      setTableSelectRow();
    })
    .catch(e => {
      console.error(e);
      processList.value = [];
    });
};

const getItemKey = (item: ANY_OBJECT) => {
  return typeof item === 'object' ? item[props.props.value] : item;
};

const isItemSelected = (item: ANY_OBJECT) => {
  const itemKey = getItemKey(item);
  return dialogSelectItems.value.some(selected => getItemKey(selected) === itemKey);
};

const setTableSelectRow = () => {
  if (!table.value || !Array.isArray(processList.value)) return;
  setTimeout(() => {
    table.value.clearCheckboxRow();
    // 只选中在当前列表中存在的项
    const itemsToSelect = processList.value.filter(isItemSelected);
    if (itemsToSelect.length > 0) {
      table.value.setCheckboxRow(itemsToSelect, true);
    }
  }, 50);
};

const onCategoryChange = (data: DictData) => {
  currentCategory.value = data;
  formFilter.categoryId = data.id;
  refreshFlowList(true);
};

const onSelectChange = ({
  checked,
  row,
}: VxeTableDefines.CheckboxChangeEventParams | VxeTableDefines.CheckboxAllEventParams) => {
  if (!dialogSelectItems.value) dialogSelectItems.value = [];

  if (row == null) {
    // 全选/取消全选时，只处理当前过滤后的列表
    if (checked) {
      // 添加新选中的项，避免重复
      filteredFlowList.value.forEach(item => {
        if (!isItemSelected(item)) {
          dialogSelectItems.value.push(item);
        }
      });
    } else {
      // 从已选中项中移除当前列表中的项
      const currentKeys = new Set(filteredFlowList.value.map(getItemKey));
      dialogSelectItems.value = dialogSelectItems.value.filter(
        item => !currentKeys.has(getItemKey(item)),
      );
    }
  } else {
    if (checked) {
      if (!isItemSelected(row)) {
        dialogSelectItems.value.push(row);
      }
    } else {
      const rowKey = getItemKey(row);
      dialogSelectItems.value = dialogSelectItems.value.filter(item => getItemKey(item) !== rowKey);
    }
  }
};

const onCellClick = ({ row }: { row: ANY_OBJECT }) => {
  const isChecked = table.value.isCheckedByCheckboxRow(row);
  table.value.setCheckboxRow(row, !isChecked);

  if (!dialogSelectItems.value) dialogSelectItems.value = [];
  if (!isChecked) {
    if (!isItemSelected(row)) {
      dialogSelectItems.value.push(row);
    }
  } else {
    const rowKey = getItemKey(row);
    dialogSelectItems.value = dialogSelectItems.value.filter(item => getItemKey(item) !== rowKey);
  }
};

const onSubmit = () => {
  if (props.dialog) {
    props.dialog.submit(dialogSelectItems.value);
  }
};

const onCancel = () => {
  if (props.dialog) {
    props.dialog.cancel();
  }
};

onMounted(() => {
  if (Array.isArray(props.value)) {
    // 只保留有效的选中项，并确保是对象格式
    dialogSelectItems.value = props.value
      .filter(item => item != null)
      .map(item => {
        if (typeof item === 'object') {
          return item;
        }
        // 如果是简单类型，创建一个对象
        return {
          [props.props.value]: item,
          [props.props.label]: item,
        };
      });
  } else {
    dialogSelectItems.value = [];
  }
  loadCategoryList();
  loadFlowList();
});
</script>

<style lang="scss" scoped>
.flow-select-dialog {
  height: 100%;

  :deep(.el-tree-node__content) {
    height: 35px;
  }

  :deep(.el-aside) {
    border-right: 1px solid #e8e8e8;
  }

  :deep(.flex-box) {
    padding: 0px;
    margin: 0px;

    .el-col {
      flex: 0 0 50% !important;
      max-width: 50% !important;
    }
  }

  .dialog-footer {
    margin-top: 16px;
    text-align: right;
  }
}

:deep(.vxe-body--row) {
  cursor: pointer;
}
</style>
